from django.shortcuts import render, get_object_or_404, redirect
from django.views import generic
from django.urls import reverse
from django.contrib.auth.decorators import login_required

import hashlib, uuid

from os.path import splitext

import logging
logger = logging.getLogger('django')

from .models import Media
from .forms import MediaForm, UploadForm

# Create your views here.

class IndexView(generic.ListView):
    model = Media

    def get_queryset(self):
        return Media.objects.order_by('-pub_date')

class TagIndex(generic.ListView):
    model = Media

    def get_queryset(self):
        return Media.objects.filter(tags__slug__in=[self.kwargs['slug']])

class DetailView(generic.DetailView):
    model = Media

def chunked_upload(request):
    model = Media
    return render(request, 'mediaconvert/chunked_upload.html')

''' Turn this into an UpdateView? '''
@login_required
def media_edit(request, pk):
    media = get_object_or_404(Media, pk=pk)
    if request.method == "POST":
        form = MediaForm(request.POST, instance=media)
        if form.is_valid():
            if 'delete' in request.POST:
                user = media.user
                media.delete()
                return redirect('accounts:detail', pk=user.pk)
            media = form.save()
            return redirect('media_detail', pk=media.pk)
    else:
        form = MediaForm(instance=media)
    return render(request, 'mediaconvert/media_edit.html', {'form': form})

def handle_uploaded_file(request, f, uri=None):
    if uri is None:
        uri = uuid.uuid4().hex
    logger.info('Logged in as %s' % request.user)
    return Media.objects.create(user=request.user, uri=uri, title=splitext(f.name)[0], upload=f)

@login_required
def media_new(request):
    if request.method == "POST":
        logger.info('Upload received: %s' % request.POST)
        logger.info('Files: %s' % request.FILES)
        form = UploadForm(request.POST, request.FILES)
        if form.is_valid():
            files = request.FILES.getlist('chunked_upload')
            logger.info('Receiving %d files' % len(files))
            for f in files:
                uploaded_file = handle_uploaded_file(request, f)
                logger.info('Received file: %s' % uploaded_file)
            logger.info('Received all files')
            if len(files) > 1:
                logger.info('Redirecting to account page')
                return redirect('accounts:detail', pk=request.user.pk)
            else:
                logger.info('Redirecting to single media page')
                return redirect('media_detail', pk=uploaded_file.pk)
    else:
        form = UploadForm()
    return render(request, 'mediaconvert/media_new.html', {'form': form})



from .models import MediaChunkedUpload
from chunked_upload.views import ChunkedUploadView, ChunkedUploadCompleteView

class MediaChunkedUploadView(ChunkedUploadView):
    model = MediaChunkedUpload
    field_name = 'chunked_upload'

#    def check_permissions(self, request):
#        # by passing here we allow non-authenticated users to upload
#        pass

def hash_for_file(hasher, f, block_size=100*1024):
    h = hasher()
    ''' Record the current position in the file object '''
    pos = f.tell()
    ''' Seek to 0 to calculate the hash properly (the whole file) '''
    f.seek(0)
    while True:
        data = f.read(block_size)
        logger.info('reading %s bytes, found %s bytes' % (block_size, len(data)))
        if not data:
           break
        h.update(data)
    ''' Return to the original position '''
    f.seek(pos)
    logger.info('hash calculated to %s' % h.hexdigest())
    return h

class MediaChunkedUploadCompleteView(ChunkedUploadCompleteView):
    model = MediaChunkedUpload

    uploaded = None

#    def check_permissions(self, request):
#        # by passing here we allow non-authenticated users to upload
#        pass

    def on_completion(self, uploaded_file, request):
        self.uploaded = handle_uploaded_file(request, uploaded_file, uri=request.POST.get('upload_id'))

        logger.info('File upload completed')

    def get_response_data(self, chunked_upload, request):
        return {
            'message': ("You successfully uploaded '%s' (%s bytes)!" %
                            (chunked_upload.filename, chunked_upload.offset)),
            'location': reverse('media_edit', kwargs={'pk': self.uploaded.pk}),
            }
